iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0

使用例外事件

在早期的很多程式語言裡並沒有例外事件的概念,我們可能會用錯誤碼或錯誤旗幟 (flag) 去捕捉例外狀況:

public class DeciceController {
    ...
    public void sendShutDown() {
        DeviceHandle handle = getHandle(DEV1);
        //  Check the state of the device
        if (handle != DeviceHandle.INVALID)  {
            //  Save the device status to the record field
            retrieveDeviceRecord(handle);
            //  If not suspended, shut down
            if (record.getStatus() != DEVICE_SUSPENDED) {
                pauseDevice(handle);
                clearDeviceWorkQueue(handle);
                closeDevice(handle);
            } else {
                logger.log("Device suspended. Unable to shut down");
            }
        } else {
            logger.log("Invalid handle for: "+ DEVI.toString());
        }
    }
    ...
}

我們可以很明顯的看出來,使用這樣的方法會使得程式碼變得雜亂。程式必須在呼叫結束後立即檢查錯誤並處理,而使用者除了很容易忽略這樣的檢查外,這也會導致深層巢狀結構。

也因此,較好的做法是,在你遇到一個錯誤的時候,拋出一個例外事件,如此,呼叫程式碼就會變得乾淨許多。錯誤處理的邏輯不該模糊原程式的邏輯。

讓我們將它修改成可偵測錯誤並拋出例外事件的程式碼:

public class DeciceController {
    ...
    public void sendShutDown() {
        try {
            tryToShutDown();
        } catch (DeviceShutDownError e) {
            logger.log(e);
        }
    }
    
    private void tryToShutDown() throws DeviceShutDownError {
        DeviceHandle handle = getHandle(DEV1);
        DeviceRecord record = retrieveDeviceRecord(handle);
        pauseDevice(handle);

        clearDeviceWorkQueue(handle);
        closeDevice(handle);
    }

    private DeviceHandle getHandle(DeviceID id) {        
        ...
        throw new DeviceShutDownError("Invalid handle for: "+ DEVI.toString());
        ...
    }
    ...
}

如此一來,原本糾纏在一起的兩件事被區分開來,程式將變得更乾淨和容易理解。

而每一個例外都應該要提供足夠的相關資訊,以便判斷發生了什麼樣的錯誤,其中包含了哪個操作發生錯誤、錯誤的型態是什麼。

小結

錯誤處理對我來說是很陌生的一塊,之前除了串接 API 取得後端資料時會做錯誤處理,其餘程式碼基本上沒用過,這次藉著閱讀該篇章認真的學習了一回。看的仔細、收穫多,分享篇幅也就會長一點,所以明天還是會繼續關於錯誤處理的內容。


上一篇
物件與資料結構
下一篇
錯誤處理(二)
系列文
重新開始學程式,【無瑕的程式碼:敏捷軟體開發技巧守則】共讀30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言